package jp.dip.ysato.excitewidget;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Coupon {
	class SIM {
		private boolean fast;
		private String tel;
		public boolean isFast() {
			return fast;
		}
		public void setFast(boolean fast) {
			this.fast = fast;
		}
		public String getTel() {
			return tel;
		}
		public void setTel(String tel) {
			this.tel = tel;
		}
	}
	private String[] remain = new String[5];
	private Calendar[] month = new Calendar[4];
	private SIM[] sims = new SIM[3];
	public String getRemain(int index) {
		return remain[index];
	}
	public void setRemain(int index, String remain) {
		this.remain[index] = remain;
	}
	public Calendar getMonth(int index) {
		return month[index];
	}
	public void setMonth(int index, String date) {
		Pattern p = Pattern.compile("(\\d+)/(\\d+)");
		Matcher m = p.matcher(date);
		m.find();
		GregorianCalendar cal = new GregorianCalendar(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) - 1, 1); 
		this.month[index] = cal;
	}
	public SIM getSIM(int index) {
		if (sims[index] == null)
			return new SIM();
		return sims[index];
	}
	public void setSIM(int index, SIM sim) {
		sims[index] = sim;
	}
	public CookieStore getLoginCookie(String user, String pass) throws ClientProtocolException, IOException {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpPost post = new HttpPost(LOGIN);
		List<NameValuePair> param = new ArrayList<NameValuePair>();
		param.add(new BasicNameValuePair("acctname", user));
		param.add(new BasicNameValuePair("passwd", pass));
		post.setEntity(new UrlEncodedFormEntity(param, HTTP.UTF_8));
		httpClient.execute(post);
		CookieStore cookiestore = httpClient.getCookieStore();
		httpClient.getConnectionManager().shutdown();
		return cookiestore;
	}
	private ByteArrayInputStream getCouponEntity(CookieStore cookies) throws ClientProtocolException, IOException {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(cookies);
		HttpGet get = new HttpGet(COUPON);
		HttpResponse res = httpClient.execute(get);
		ByteArrayInputStream in = new ByteArrayInputStream(EntityUtils.toByteArray(res.getEntity()));
		httpClient.getConnectionManager().shutdown();
		return in;
	}
	private ByteArrayInputStream getFastInfo(CookieStore cookies) throws ClientProtocolException, IOException {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(cookies);
		HttpGet get = new HttpGet(FAST);
		HttpResponse res = httpClient.execute(get);
		ByteArrayInputStream in = new ByteArrayInputStream(EntityUtils.toByteArray(res.getEntity()));
		httpClient.getConnectionManager().shutdown();
		return in;
	}
	private ByteArrayInputStream pickupTable(ByteArrayInputStream is, String marker) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
		StringBuilder sb = new StringBuilder();
		String s;
		boolean content = false;
		while((s = br.readLine()) != null) {
			if (s.contains(marker)) 
				content = true;
			if (content) {
				sb.append(s).append('\n');
				if (s.contains("</table>")) {
					break;
				}
			}
		}
		return new ByteArrayInputStream(sb.toString().getBytes());
	}
	private static final String LOGIN="https://ssl.excite.co.jp/idcenter/login/?_cn=proxy&pname=bbe&brand=xct&" +
			"targeturl=https%3A%2F%2Fssl.excite.co.jp%2Fbb%2Fcdn%2Flte%2Fdocomo%2Fcoupon%2F";
	private static final String COUPON="https://ssl.excite.co.jp/bb/cdn/lte/docomo/coupon/";
	private static final String FAST="https://ssl.excite.co.jp/bb/cdn/lte/docomo/onoff/";
	private CookieStore cookies;

	public void getinfo(CookieStore cookies) {
		try {
			ByteArrayInputStream is = getCouponEntity(cookies);
			is = pickupTable(is, "\"o2\"");
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(is);
			NodeList td = document.getElementsByTagName("td");
			for (int i = 0; i < td.getLength(); i += 2)
				setRemain(i / 2, td.item(i).getTextContent());
			for (int i = 1; i < td.getLength(); i += 2)
				setMonth((i - 1) / 2, td.item(i).getTextContent());
			is = getFastInfo(cookies);
			is = pickupTable(is, "\"o2 txtC\"");
			factory = DocumentBuilderFactory.newInstance();
			builder = factory.newDocumentBuilder();
			document = builder.parse(is);
			td = document.getElementsByTagName("td");
			SIM sim = null;
			for(int i = 0; i < td.getLength(); i++)
				switch(i % 5) {
					case 0:
						sim = new SIM();
						break;
					case 1:
						sim.setFast(td.item(i).getTextContent().equals("ON"));
						break;
					case 4:
						sim.setTel(td.item(i).getTextContent());
						setSIM(i / 5, sim);
						break;
				}
		} catch (ClientProtocolException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private void applystate(List<NameValuePair> param) throws ClientProtocolException, IOException {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(cookies);
		HttpPost post = new HttpPost(FAST);
		post.setEntity(new UrlEncodedFormEntity(param, HTTP.UTF_8));
		HttpResponse res = httpClient.execute(post);
		ByteArrayInputStream in = new ByteArrayInputStream(EntityUtils.toByteArray(res.getEntity()));
		httpClient.getConnectionManager().shutdown();
		BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
		param = new ArrayList<NameValuePair>();
		String s;
		while((s = br.readLine()) != null) {
			if (!s.contains("_return") && s.contains("<input")) {
				int name = s.indexOf("name=") + 6;
				int value = s.indexOf("value") + 7;
				param.add(new BasicNameValuePair(s.substring(name, s.indexOf('"', name)), s.substring(value, s.indexOf('"', value))));
			}
		}
		httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(cookies);
		post = new HttpPost(FAST);
		post.setEntity(new UrlEncodedFormEntity(param, HTTP.UTF_8));
		httpClient.execute(post);
		httpClient.getConnectionManager().shutdown();
	}

	public void setfast(CookieStore cookies, String tel, boolean state) {
		ByteArrayInputStream is;
		try {
			is = getFastInfo(cookies);
			BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
			String s;
			List<NameValuePair> param = new ArrayList<NameValuePair>();
			while((s = br.readLine()) != null) {
				if (!s.contains("<td>") && s.contains("<input")) {
					int name = s.indexOf("name=") + 6;
					int value = s.indexOf("value") + 7;
					param.add(new BasicNameValuePair(s.substring(name, s.indexOf('"', name)), s.substring(value, s.indexOf('"', value))));
				}
			}
			is.reset();
			is = pickupTable(is, "\"o2 txtC\"");
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(is);
			NodeList td = document.getElementsByTagName("td");
			boolean curstate = false;
			String simname = null;
			String simvalue = null;
			for(int i = 0; i < td.getLength(); i++)
				switch(i % 5) {
					case 0:
						NodeList input = td.item(i).getChildNodes();
						NamedNodeMap map = input.item(0).getAttributes();
						simname = map.getNamedItem("name").getNodeValue();
						simvalue = map.getNamedItem("value").getNodeValue();
						break;
					case 1:
						curstate= td.item(i).getTextContent().equals("ON");
						break;
					case 4:
						if(td.item(i).getTextContent().equals(tel) &&
								curstate != state) {
							param.add(new BasicNameValuePair(simname, simvalue));
							applystate(param);
						}
						break;
				}
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
